package part22网络编程.群聊;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Vector;


/**
 * 聊天类
 * 发消息给所有的在线的客户端
 * 
 * @author Administrator
 *
 */
class MyChatThread2 extends Thread {

	private Socket client; // 客户端
	
	public  MyChatThread2(Socket client) {
		this.client = client;
	}
	@Override
	public void run() {
		DataInputStream dis = null; // 数据输入流
		DataOutputStream dos = null; // 数据输出流
		try {
			// 不停交互
			// 调用Socket类的getOutputStream()和getInputStream获取输出流和输入流，开始网络数据的发送和接收。
			dis = new DataInputStream(client.getInputStream());
			
			// 不停的读和写
			while (true) {
				// 读：读取客户端的消息
				String content = dis.readUTF();
				System.out.println(client.getRemoteSocketAddress() + " : " + content);
				
				// 写: 发送消息给客户端
				// 群聊提升3：服务器应该把客户端发来的消息，发送给所有的在线客户端
				// 遍历客户端列表(集合)
				for (Socket c : Server3.clientVector) {
					
					// 现在是要把消息发给所有的客户端，所以每一个客户端都要有一个自己的输出流
					dos = new DataOutputStream(c.getOutputStream());
					
					// 将读到的信息发送出去 client.getRemoteSocketAddress()可以知道是哪一个客户端发送的信息
					dos.writeUTF( client.getRemoteSocketAddress() +" : " +  content);
				}
			}
		} catch (IOException e) {
//			e.printStackTrace();
			System.out.println(client.getRemoteSocketAddress() + "已下线！");// 提示用户下线信息
			// 群聊提升4：用户下线，从集合中踢出
			Server3.clientVector.remove(client);
			System.out.println("在线用户数量：" + Server3.clientVector.size());
		} finally {
			try {
				if (dos != null) {
					dos.close();
				}
				if (dis != null) {
					dis.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}

/**
 * 服务端 1对多
 * 1个服务端可以操作多个客户端
 * 群聊
 * @author Administrator
 *
 */
public class Server3 {
	
	// 群聊提升1：定义一个集合存储所有的在线客户端
	static Vector<Socket> clientVector = new  Vector<>();

	public static void main(String[] args) {
		Server3 server1 = new Server3();
		server1.testServer();
	}
	public void testServer() {
		ServerSocket server = null; // 服务端套接字
		Socket client = null; // 客户端 通信套接字
		try {
			// 调用ServerSocket(int port)创建一个服务器端套接字，并绑定到指定端口上；
			server = new ServerSocket(6666);
			System.out.println("服务器启动成功");

			// 提升1：不停的监听客户端的连接
			while (true) {

				// 调用accept()，监听连接请求，如果客户端请求连接，则接受连接，返回通信套接字。
				client = server.accept();
				System.out.println(client.getRemoteSocketAddress() + "上线~");
				
				// 群聊提升2： 将上线的客户端存储到集合中
				clientVector.add(client);
				System.out.println("在线用户数量：" + clientVector.size());

				// 提升2：新建一个读和写的线程,进入就绪状态
				new MyChatThread2(client).start();
			}
		} catch (IOException e) {
			 e.printStackTrace();
		} finally {
			try {
				// 最后关闭通信套接字。
				if (client != null) {
					client.close();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
}
